#include <EventSender.hpp>
#include <Event.hpp>
#include "stl_impl_eds.hpp"

struct event_bind_struct{
  EventSender *sender;
  Event       *event;
};

EventSender::EventSender()
  :_impl( new stl_impl_eds<receiver_struct>() )
{}

EventSender::~EventSender()
{
  _impl->for_each( do_clean_listener, this );

  stl_impl_eds<receiver_struct> *__p = dynamic_cast< stl_impl_eds<receiver_struct>* >(_impl);
  delete __p;
}

void EventSender::do_clean_listener( void *_arg, long _id, const receiver_struct &_rcv_struct )
{
  EventSender *__p = static_cast<EventSender*>(_arg);
  EventHandler __handler = _rcv_struct.eventHandler;

  _rcv_struct.listenningReceiver->nolistenEvent(_id, __p, __handler);
}

bool EventSender::isAboutToSend( long _id )
{
  return will_send(_id);
}

int EventSender::eventHappen( Event &_e )
{
  return send_event( _e );
}

bool EventSender::will_send( long _id )
{
  return true;
}

int EventSender::do_send_loop(void *_b_struct, const EventSender::receiver_struct &_rcv_struct)
{
  event_bind_struct *__bind_struct = static_cast<event_bind_struct*>(_b_struct);
  __bind_struct->event->setSender(__bind_struct->sender);
  __bind_struct->event->setReceiver(_rcv_struct.listenningReceiver);

  (*_rcv_struct.eventHandler)( *__bind_struct->event );
}

int EventSender::send_event( Event &_e )
{
  event_bind_struct __bind_struct;
  __bind_struct.sender = this;
  __bind_struct.event = &_e;
  _impl->for_each( _e.eventID, do_send_loop, &__bind_struct);
}

bool EventSender::has_event_dispatch_struct( long _id, EventReceiver *_recver, EventHandler _listener )
{
  receiver_struct __rcv_struct;
  __rcv_struct.listenningReceiver = _recver;
  __rcv_struct.eventHandler = _listener;

  return _impl->has_node(_id, __rcv_struct);
}

bool EventSender::add_event_dispatch_struct( long _id, EventReceiver *_recver, EventHandler _listener )
{
  bool __ret = false;
  if( will_send(_id) )
    {
      receiver_struct __rcv_struct;
      __rcv_struct.listenningReceiver = _recver;
      __rcv_struct.eventHandler = _listener;
      _impl->add_node(_id, __rcv_struct);

      __ret = true;
    }

  return __ret;
}

void EventSender::del_event_dispatch_struct( long _id, EventReceiver *_recver, EventHandler _listener )
{
  receiver_struct __rcv_struct;
  __rcv_struct.listenningReceiver = _recver;
  __rcv_struct.eventHandler = _listener;
  _impl->del_node(_id, __rcv_struct);
}

bool operator<(const EventSender::receiver_struct &a, const EventSender::receiver_struct &b )
{
  unsigned int __a, __b;
  __a = reinterpret_cast<unsigned int>(a.listenningReceiver);
  __b = reinterpret_cast<unsigned int>(b.listenningReceiver);
  if( __a == __b )  
    {
      __a = (unsigned int&)a.eventHandler;
      __b = (unsigned int&)b.eventHandler;
      return __a < __b;
    }
  return __a < __b;
}

